package emulator.unittest.hardware.nmos6502.commands;

import static org.junit.Assert.assertEquals;

import org.junit.Before;
import org.junit.Test;

import emulator.EmulatorException;
import emulator.hardware.HwByte;
import emulator.hardware.clock.ClockImplementation;
import emulator.hardware.memory.MemoryBlock;
import emulator.hardware.nmos6502.Cpu6502;
import emulator.hardware.nmos6502.commands.PLA;
import emulator.hardware.nmos6502.operands.NoOperand;

public class PLATest {

	private Cpu6502 cpu;
	private MemoryBlock memory;

	@Before
	public void setUp()
	{
		cpu = new Cpu6502();
		memory = new MemoryBlock(65536);
		ClockImplementation clock = new ClockImplementation();
		cpu.attach(memory, clock);
	}
	
	@Test
	public void testPopZero() throws EmulatorException {
		checkPopAndFlags(0, true, false);
	}

	@Test
	public void testPopPositive() throws EmulatorException {
		checkPopAndFlags(0x7A, false, false);
	}

	@Test
	public void testPopNegative() throws EmulatorException {
		checkPopAndFlags(0xAA, false, true);
	}

	private void checkPopAndFlags(int test_number, boolean zero_expected,
			boolean negative_expected) throws EmulatorException {
		cpu.setSP(new HwByte(0xFE));
		memory.write(0x1FF, test_number);
		cpu.setAccu(new HwByte(0x55));

		new PLA().execute(cpu, new NoOperand());
		assertEquals(new HwByte(0xFF), cpu.getSP());
		assertEquals(new HwByte(test_number), cpu.getAccu());
		
		assertEquals(zero_expected, cpu.getFlags().getZero());
		assertEquals(negative_expected, cpu.getFlags().getNegative());
	}
}
